Skip to content

Conversation

@billyean
Copy link

@billyean billyean commented Nov 6, 2025

Received the following diagnostics while designing an application with postgres-nio 1.27.0...1.29.0:

00:56:35.221 [NotificationsListener.swift:517] - Notifications: Failed to LISTEN {error: "PSQLError(code: server, serverInfo: [sqlState: 57P01, file: be-secure.c, line: 209, message: terminating connection due to unexpected postmaster exit, routine: secure_read, localizedSeverity: FATAL, severity: FATAL])", topic: hawq_39}
00:56:35.222 [PostgresChannelHandler.swift:104] - Channel error caught. {psql_error: "I/O on closed channel", psql_connection_id: "1"}
00:56:35.222 [NotificationsListener.swift:286] - Notifications: Restarting subscription {topic: hawq_205}
00:56:35.222 [NotificationsListener.swift:148] - Notifications: Starting listening {psql.conn.id: "0", psql.conn.isClosed: true, topic: hawq_157}

SWIFT TASK CONTINUATION MISUSE: listen(_:) leaked its continuation without resuming it. This may cause tasks waiting on it to remain suspended forever.

And then the application deadlocks because listen() doesn't ever return.

Reproduction:

  1. The code looks like that:

             try await self.postgresClient.withConnection { connection in
                 148: log.debug("Notifications: Starting listening", metadata: [       
                     "topic": "\(topic)",                                         
                     "psql.conn.id": "\(connection.id)",                          
                     "psql.conn.isClosed": "\(connection.isClosed)"               
                 ])                                                               
                 sequence = try await connection.listen(topic.stringValue)        
                 154: log.debug("Notifications: Now listening", metadata: [            
                     "topic": "\(topic)",                                          
                     "psql.conn.id": "\(connection.id)",                          
                     "psql.conn.isClosed": "\(connection.isClosed)"               
                 ])
    
  2. brew services restart postgresql

  3. The error log similar to the log above gets generated, and the system goes into a deadlock.

Notice the log from line 148 is present, the connection appears to be CLOSED, and then the line 154 is unreachable. This might mean that listen() state machine is not correct on closed channels and result in deadlock.

@codecov
Copy link

codecov bot commented Nov 6, 2025

Codecov Report

❌ Patch coverage is 87.50000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.26%. Comparing base (7900fed) to head (ff1ba85).

Files with missing lines Patch % Lines
Sources/PostgresNIO/New/NotificationListener.swift 75.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #600      +/-   ##
==========================================
+ Coverage   76.01%   76.26%   +0.25%     
==========================================
  Files         134      134              
  Lines       10098    10112      +14     
==========================================
+ Hits         7676     7712      +36     
+ Misses       2422     2400      -22     
Files with missing lines Coverage Δ
...es/PostgresNIO/Connection/PostgresConnection.swift 82.63% <100.00%> (+0.21%) ⬆️
.../Connection State Machine/ListenStateMachine.swift 73.88% <100.00%> (+8.20%) ⬆️
...urces/PostgresNIO/New/PostgresChannelHandler.swift 91.99% <100.00%> (+1.27%) ⬆️
Sources/PostgresNIO/New/NotificationListener.swift 87.05% <75.00%> (+1.34%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Collaborator

@fabianfett fabianfett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @billyean, that's a great first PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants